using System;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Formatter;

namespace Admin.NET.Application.Mqtt;

public class IotMqttClient
{
	/// <summary>
	/// 实体
	/// </summary>
	public IMqttClient mqttClient;

	private MqttClientOptions mqttClientOptions;

	private readonly MqttSettingsOptions setting;

	/// <summary>
	/// 断开连接
	/// </summary>
	public event Func<MqttClientDisconnectedEventArgs, Task> MqttClient_DisconnecteOtherdAsync;

	/// <summary>
	/// 连接
	/// </summary>
	public event Func<MqttClientConnectedEventArgs, Task> MqttClient_ConnectedAsync;

	/// <summary>
	/// 数据接受
	/// </summary>
	public event Func<MqttApplicationMessageReceivedEventArgs, Task> MqttClient_ApplicationMessageReceivedAsync;

	/// <summary>
	///             狗澡函数
	/// </summary>
	/// <param name="_setting"></param>
	public IotMqttClient(MqttSettingsOptions _setting)
	{
		setting = _setting;
	}

	public void InitMqtt()
	{
		MqttFactory mqttFactory = new MqttFactory();
		string clientId = Guid.NewGuid().ToString("N");
		mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer(setting.Host, setting.Port).WithProtocolVersion(MqttProtocolVersion.V500).WithClientId(clientId)
			.WithCleanSession(value: false)
			.WithKeepAlivePeriod(TimeSpan.FromSeconds(30.0))
			.WithCredentials(setting.UserName, setting.Password)
			.Build();
		mqttClient = mqttFactory.CreateMqttClient();
		mqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
		mqttClient.ConnectedAsync += this.MqttClient_ConnectedAsync;
		mqttClient.ApplicationMessageReceivedAsync += this.MqttClient_ApplicationMessageReceivedAsync;
		mqttClient.ConnectAsync(mqttClientOptions).Wait();
	}

	private async Task MqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
	{
		TimeSpan delay = TimeSpan.FromSeconds(5.0);
		while (mqttClient != null && !mqttClient.IsConnected)
		{
			try
			{
				await Task.Delay(delay);
				await mqttClient.ConnectAsync(mqttClientOptions);
				Console.WriteLine("Reconnected to MQTT broker.");
			}
			catch (Exception ex)
			{
				Console.WriteLine("Reconnect failed: " + ex.Message);
			}
		}
	}
}
